package handler

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"io"
	"onvif_server/api"
	"onvif_server/api/system"
	"onvif_server/internal/errcode"
	"onvif_server/internal/service"
	ws2 "onvif_server/pkg/ws"
	"strings"
)

type SystemHandler struct {
	*Handler
	wsManage   *ws2.Manage
	sysService service.SystemService
}

func NewSystemHandler(handler *Handler, sysService service.SystemService, wsManage *ws2.Manage) *SystemHandler {
	h := &SystemHandler{
		Handler:    handler,
		sysService: sysService,
		wsManage:   wsManage,
	}
	return h
}

func (h *SystemHandler) Info(ctx *gin.Context) {
	res, err := h.sysService.Info(ctx)
	api.Response(ctx, err, res)
}

func (h *SystemHandler) Reboot(ctx *gin.Context) {
	req := system.RebootReq{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		api.Fail(ctx, errcode.ErrInvalidParams.Wrap(err))
		return
	}
	err := h.sysService.Reboot(ctx, UserId(ctx), req.Password)
	api.Response(ctx, err, nil)
}

func (h *SystemHandler) Upgrade(ctx *gin.Context) {
	err := h.sysService.Upgrade(ctx)
	api.Response(ctx, err, nil)
}

func (h *SystemHandler) Discovery(ctx *gin.Context) {
	res, err := h.sysService.Discovery(ctx)
	api.Response(ctx, err, res)
}

func (h *SystemHandler) Upload(ctx *gin.Context) {
	res, err := h.sysService.Upload(ctx, "file")
	api.Response(ctx, err, res)
}

func (h *SystemHandler) GetUploadFile(ctx *gin.Context) {
	file := ctx.Param("file")
	if file == "" {
		ctx.AbortWithStatus(404)
		return
	}
	rc, ct, err := h.sysService.FileOutput(ctx, file)
	if err != nil {
		api.Fail(ctx, err)
		return
	}
	defer rc.Close()
	if ct != "" {
		ctx.Writer.Header().Set("Content-Type", ct)
		//ctx.Header("Context-Type", ct)
	}
	fmt.Println(ct)
	if _, err = io.Copy(ctx.Writer, rc); err != nil {
		ctx.AbortWithStatus(500)
	}
}

func (h *SystemHandler) Ws(ctx *gin.Context) {
	wsConn, err := UpGrader(ctx)
	if err != nil {
		api.Fail(ctx, errcode.ErrServer.Wrap(err))
	}
	h.wsManage.Register(wsConn)
}

func (h *SystemHandler) SubscribeReport(ctx *gin.Context) {
	headers := make([]string, 0)
	for k, v := range ctx.Request.Header {
		headers = append(headers, fmt.Sprintf("%s=%s", k, strings.Join(v, ",")))
	}
	b, err := io.ReadAll(ctx.Request.Body)
	h.log.Info("SubscribeReport", zap.Strings("header", headers), zap.ByteString("body", b), zap.Error(err))
}
